package com.dragon.modules.yuegou.service.impl.act;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dragon.common.exception.DragonException;
import com.dragon.common.web.PageRequest;
import com.dragon.modules.yuegou.entity.act.GiftEntity;
import com.dragon.modules.yuegou.entity.act.GiftGoodsRefEntity;
import com.dragon.modules.yuegou.entity.act.GiftRecordEntity;
import com.dragon.modules.yuegou.entity.busd.DistrictEntity;
import com.dragon.modules.yuegou.entity.coupon.CouponEntity;
import com.dragon.modules.yuegou.entity.coupon.CouponTemplateEntity;
import com.dragon.modules.yuegou.entity.order.OrderEntity;
import com.dragon.modules.yuegou.entity.product.SkuEntity;
import com.dragon.modules.yuegou.entity.product.SpuEntity;
import com.dragon.modules.yuegou.entity.system.UserEntity;
import com.dragon.modules.yuegou.enums.act.GiftCommodityType;
import com.dragon.modules.yuegou.enums.act.GiftStatus;
import com.dragon.modules.yuegou.enums.act.GiftType;
import com.dragon.modules.yuegou.enums.code.ActivityCode;
import com.dragon.modules.yuegou.enums.code.PointsCode;
import com.dragon.modules.yuegou.enums.order.OrderStatus;
import com.dragon.modules.yuegou.mapper.act.GiftMapper;
import com.dragon.modules.yuegou.model.act.Gift;
import com.dragon.modules.yuegou.model.act.GiftGoodsRef;
import com.dragon.modules.yuegou.model.coupon.CouponTemplate;
import com.dragon.modules.yuegou.model.product.Sku;
import com.dragon.modules.yuegou.model.product.Spu;
import com.dragon.modules.yuegou.query.act.GiftGoodsRefQuery;
import com.dragon.modules.yuegou.query.act.GiftQuery;
import com.dragon.modules.yuegou.query.act.GiftRecordQuery;
import com.dragon.modules.yuegou.request.CompleteInfoListPageRequest;
import com.dragon.modules.yuegou.response.RegisterGiftSituation;
import com.dragon.modules.yuegou.service.act.GiftGoodsRefService;
import com.dragon.modules.yuegou.service.act.GiftRecordService;
import com.dragon.modules.yuegou.service.act.GiftService;
import com.dragon.modules.yuegou.service.busd.DistrictService;
import com.dragon.modules.yuegou.service.coupon.CouponService;
import com.dragon.modules.yuegou.service.coupon.CouponTemplateService;
import com.dragon.modules.yuegou.service.order.OrderService;
import com.dragon.modules.yuegou.service.product.SkuService;
import com.dragon.modules.yuegou.service.product.SpuService;
import com.dragon.modules.yuegou.service.system.UserService;
import com.dragon.modules.yuegou.web.Check;
import com.dragon.modules.yuegou.web.DataSliceUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 送礼表 服务实现
 *
 * @author pbuilder generated
 * @date 2019-11-19 19:34:47
 * @version 2.0
 */
@Slf4j
@Service("actGiftService")
public class GiftServiceImpl
		extends ServiceImpl<GiftMapper, GiftEntity>
		implements GiftService {

	@Autowired
	private CouponTemplateService couponTemplateService;

    @Autowired
    private SkuService skuService;

    @Autowired
    private SpuService spuService;

	@Autowired
	private UserService userService;

	@Autowired
	private DistrictService districtService;

	@Autowired
	private GiftRecordService giftRecordService;

	@Autowired
	private OrderService orderService;

	@Autowired
	private CouponService couponService;

	@Autowired
	private GiftGoodsRefService giftGoodsRefService;

	@Override
	public IPage<Gift> search(PageRequest page, Gift gift) {
		GiftQuery query = new GiftQuery();
		query.setBusdId(DataSliceUtils.currentBusdId());
		query.setDel(false);
		if (Objects.nonNull(gift.getStatus())) {
			query.setStatus(gift.getStatus());
		}
		if (StringUtils.isNotBlank(gift.getCommodityName())) {
				query.commodityName().like(gift.getCommodityName());
		}
		if (StringUtils.isNotBlank(gift.getActivityName())) {
				query.activityName().like(gift.getActivityName());
		}
		if (Objects.nonNull(gift.getCommodityType())) {
			query.setCommodityType(gift.getCommodityType());
		}
		if (Objects.nonNull(gift.getType())) {
			query.setType(gift.getType());
		}
		QueryWrapper<GiftEntity> wrapper = query.toQueryWrapper();
		wrapper.orderByAsc(GiftEntity.COL_SORT_NO);
		wrapper.orderByDesc(GiftEntity.COL_CREATED_TIME);
		IPage<GiftEntity> iPage = new Page<>(page.getPage(), page.getSize(), true);
		IPage<GiftEntity> page1 = baseMapper.selectPage(iPage, wrapper);
		DistrictEntity district = districtService.getById(DataSliceUtils.currentBusdId());

		IPage<Gift> giftIPage = page1.convert(Gift::new);
		for (Gift record : giftIPage.getRecords()) {
            GiftGoodsRefQuery refQuery = new GiftGoodsRefQuery();
            refQuery.setGiftId(record.getId());
            List<GiftGoodsRefEntity> list = giftGoodsRefService.list(refQuery.toQueryWrapper());
            List<String> collect = list.stream().map(GiftGoodsRefEntity::getCommodityName).filter(Objects::nonNull).collect(Collectors.toList());
            String join = String.join(",", collect);
            record.setCommodityName(join);
            UserEntity user = userService.getById(record.getCreatedBy());
			//如果用户昵称为空则设置为登录名
			if (StringUtils.isEmpty(user.getNickName())) {
				record.setCreatedName(user.getUsername());
			} else {
				record.setCreatedName(user.getNickName());
			}
			record.setBusdName(district.getBcName());
		}
		return giftIPage;
	}

	@Override
	@Transactional
	public void saveGift(Gift gift) {
		Check.notEmpty(gift.getBusdId(),"商圈ID");
		Check.notNull(gift.getCommodityType(),"请确认送礼物品类型");
		Check.notNull(gift.getActivityName(),"请确认活动名称");
		Check.length(gift.getActivityName(), 0, 30, "活动名称不能超过三十字");
		Check.notNull(gift.getActivityBeginTime(),"请确认活动开始时间！");
		Check.notNull(gift.getActivityEndTime(),"请确认活动结束时间！");
		if (gift.getActivityBeginTime().isAfter(gift.getActivityEndTime())) {
			throw new DragonException(ActivityCode.ACTIVITY_BEGIN_TIME_MUST_BEFORE_END_TIME);
		}
		if (gift.getActivityBeginTime().isBefore(LocalDateTime.now())) {
			gift.setStatus(GiftStatus.PROCESSIONG);
		}
		if (gift.getActivityEndTime().isBefore(LocalDateTime.now())) {
			throw new DragonException(ActivityCode.ACTIVITY_TIME_IS_NOT_CORRECT);
		}
        if (gift.getType().equals(GiftType.PERFECT)) {
            //校验活动名称在相同商圈是否重复
            GiftQuery query = new GiftQuery();
            query.setDel(false);
            query.setType(GiftType.PERFECT);
            query.setActivityName(gift.getActivityName());
            Long count = count(query.toQueryWrapper());
            if (count > 0) {
                throw new DragonException(ActivityCode.THE_NAME_OF_THE_EVENT_ITEM_CANNOT_BE_REPEATED);
            }
        }
		gift.setDel(false);
		switch (gift.getCommodityType()) {
			//赠送积分
			case POINTS:
				saveGiftPoint(gift);
				break;
				//赠送停车券
			case PARK_COUPON:
				saveGiftPark(gift);
				break;
				//赠送商品
			case VOUCHER_COUPON:
				saveGiftSpu(gift);
				break;
				//赠送优惠券
			case COUP:
				saveGiftCoup(gift);
				break;
				//赠送套餐
			case PACKAGE:
				saveGiftPackage(gift);
				break;
			default:
				log.error("保存礼物类型未知");
				throw new DragonException(ActivityCode.TODO);

		}
	}

	private void saveGiftPackage(Gift gift) {
		List<GiftGoodsRef> refs = gift.getRefs();
		if (gift.getActivityEndTime().isBefore(LocalDateTime.now())) {
			throw new DragonException(ActivityCode.ACTIVITY_TIME_IS_NOT_CORRECT);
		}
		baseMapper.insert(gift);
		List<String> packageIdList = refs.stream().map(GiftGoodsRef::getArticleId).distinct().collect(Collectors.toList());
		List<SpuEntity> spuList = spuService.listByIds(packageIdList);

		for (GiftGoodsRef ref : refs) {
			ref.setGiftId(gift.getId());
			SpuEntity spu = spuList.stream().filter(a -> ref.getArticleId().equals(a.getId())).findFirst().orElse(new Spu());
			ref.setCommodityName(spu.getTitle());
			ref.setDel(false);
			ref.setCreatedBy(gift.getCreatedBy());
			ref.setCreatedTime(LocalDateTime.now());
			giftGoodsRefService.save(ref);

		}

	}

	private void saveGiftCoup(Gift gift) {
		List<GiftGoodsRef> refs = gift.getRefs();
		if (gift.getActivityEndTime().isBefore(LocalDateTime.now())) {
			throw new DragonException(ActivityCode.ACTIVITY_TIME_IS_NOT_CORRECT);
		}
		baseMapper.insert(gift);
		List<String> articleIdList = refs.stream().map(GiftGoodsRef::getArticleId).distinct().collect(Collectors.toList());
		List<CouponTemplateEntity> templates = couponTemplateService.listByIds(articleIdList);
		for (GiftGoodsRef ref : refs) {
			if (!CollectionUtils.isEmpty(templates)) {
				CouponTemplateEntity template = templates.stream().filter(a -> ref.getArticleId().equals(a.getId())).findFirst().orElse(new CouponTemplate());
				ref.setCommodityName(template.getTitle());
			}
			ref.setGiftId(gift.getId());
			ref.setDel(false);
			ref.setCreatedBy(gift.getCreatedBy());
			ref.setCreatedTime(LocalDateTime.now());
			giftGoodsRefService.save(ref);

		}

	}

	@Override
    public void overGift(String id) {
        GiftEntity gift = getById(id);
        gift.setStatus(GiftStatus.OVER);
        baseMapper.updateById(gift);
    }

    @Override
    public Gift searchOne(String id) {
        GiftEntity entity = getById(id);
        Check.notNull(entity,"请确认活动！");
		Gift gift = new Gift(entity);
        switch (gift.getCommodityType()) {
            case PARK_COUPON:
                CouponTemplateEntity couponTemplate = couponTemplateService.getById(gift.getArticleId());
				gift.setCouponTemplate(new CouponTemplate(couponTemplate));
                break;
            case VOUCHER_COUPON:
				SkuEntity sku = skuService.getById(gift.getArticleId());
				gift.setSku(new Sku(sku));
				SpuEntity spu = spuService.getById(sku.getSpuId());
				gift.setSpuBeginTime(spu.getBeginTime());
				gift.setSpuEndTime(spu.getEndTime());
				break;
            case POINTS:
                break;
            default:
                log.error("查询注册送礼商品类型出错"+gift.getId());
                throw new DragonException(ActivityCode.TODO);
        }
        return gift;
    }

	/**
	 * 更新状态
	 */
	@Override
	public int updateGiftStatus() {
		GiftQuery query = new GiftQuery();
		query.setDel(false);
		query.status().between(GiftStatus.ABOUT_START, GiftStatus.PROCESSIONG);
		List<GiftEntity> gifts = list(query.toQueryWrapper());
		ArrayList<GiftEntity> list = new ArrayList<>();
		for (GiftEntity gift : gifts) {
			//未开始时间到时设置成赠送中
			if (GiftStatus.ABOUT_START.equals(gift.getStatus())
			&&(gift.getActivityBeginTime().isBefore(LocalDateTime.now())||gift.getActivityBeginTime().isEqual(LocalDateTime.now()) )) {
				gift.setStatus(GiftStatus.PROCESSIONG);
				list.add(gift);
			}
			//赠送中变成已结束
			if (GiftStatus.PROCESSIONG.equals(gift.getStatus())
			&& (gift.getActivityEndTime().isBefore(LocalDateTime.now()) || gift.getActivityEndTime().isEqual(LocalDateTime.now()))) {
				gift.setStatus(GiftStatus.OVER);
				list.add(gift);
			}
		}
		if (CollectionUtils.isEmpty(list)){
			return 0;
		}
		for (GiftEntity gift : list){
			baseMapper.updateById(gift);
		}
		return list.size();
	}

	@Override
	public void updateGiftSort(int sort, String id) {
		GiftEntity gift = getById(id);
		if (Objects.isNull(gift)) {
			return;
		}
		gift.setSortNo(sort);
		baseMapper.updateById(gift);
	}

	@Override
	public void deleteGift(String id, String by) {
		GiftEntity gift = this.getById(id);
		gift.setDel(true);
		gift.setDelBy(by);
		gift.setDelTime(LocalDateTime.now());
		baseMapper.updateById(gift);
	}

	@Override
	public RegisterGiftSituation searchSituation(String id) {
		//根据id查询出相关礼物
		GiftEntity gift = getById(id);
		//依据礼物id查询出发放的记录
		GiftRecordQuery query = new GiftRecordQuery();
		query.setGiftId(id);
		List<GiftRecordEntity> list = giftRecordService.list(query.toQueryWrapper());
		//构建返回值
		RegisterGiftSituation situation = new RegisterGiftSituation(0,0,0);
		//如果传递的是没有记录或者没有相关礼物返回默认值
		if (Objects.isNull(gift) || CollectionUtils.isEmpty(list)||list.size() < 1) {
			return situation;
		}

		switch (gift.getCommodityType()) {
			//礼物的类型是积分
			case POINTS:
				situation.setIssuedNumber(list.size());
				situation.setTotalPoint(list.size() * gift.getArticlePoints());
				break;
				//礼物的类型是商品
			case VOUCHER_COUPON:
				List<String> collect = list.stream().map(giftRecord -> giftRecord.getGiveId()).collect(Collectors.toList());
				List<OrderEntity> orders = orderService.listByIds(collect);
				int usedNumber = 0;
				//遍历订单列表，计算出订单状态为已完成的订单计数
				for (OrderEntity order : orders) {
					if (OrderStatus.SUCCEED.equals(order.getStatus())) {
						usedNumber = usedNumber + 1;
					}
				}
				situation.setIssuedNumber(list.size());
				situation.setUsedNumber(usedNumber);
				break;
			//礼物的类型是商品
			case PARK_COUPON:
				List<String> coupons = list.stream().map(giftRecord -> giftRecord.getGiveId()).collect(Collectors.toList());
				List<CouponEntity> couponList = couponService.listByIds(coupons);
				situation.setIssuedNumber(list.size());
				int used = 0;
				//遍历券包列表，计算出券包中已经使用的数量
				for (CouponEntity coupon : couponList) {
					if (coupon.getUsed()) {
						used = used + 1;
					}
				}
				situation.setUsedNumber(used);
				break;
		}

		return situation;
	}

	@Override
	public IPage<Gift> completeListPage(PageRequest page, CompleteInfoListPageRequest query) {
		GiftQuery giftQuery = new GiftQuery();
		giftQuery.setDel(false);
		giftQuery.setType(GiftType.PERFECT);
		giftQuery.setBusdId(query.getBusdId());
		if (StringUtils.isNotEmpty(query.getActiveName())) {
			giftQuery.activityName().like(query.getActiveName());
		}
		if (query.getType() != null) {
			giftQuery.setCommodityType(GiftCommodityType.from(query.getType()));
		}
		if (query.getCondition() != null) {
			switch (query.getCondition()) {
				case 0:
					giftQuery.activityBeginTime().gt(LocalDateTime.now());
					break;
				case 1:
					giftQuery.activityEndTime().ge(LocalDateTime.now());
					giftQuery.activityBeginTime().le(LocalDateTime.now());
					break;
				case 2:
					giftQuery.activityEndTime().lt(LocalDateTime.now());
					break;

			}
		}
		if (query.getStatus() != null) {
			giftQuery.setOpenType(query.getStatus()==1);
		}
		IPage<GiftEntity> iPage = new Page<>(page.getPage(), page.getSize(), true);
		IPage<GiftEntity> entityIPage = baseMapper.selectPage(iPage,giftQuery.toQueryWrapper());
		return entityIPage.convert(Gift::new);
	}

	@Override
	public void startStop(String id, boolean onOff) {
		GiftEntity gift = baseMapper.selectById(id);
		gift.setOpenType(onOff);
		baseMapper.updateById(gift);
	}

	@Override
	public Integer searchBusdRefs(String busdId, String memberId) {
		return baseMapper.searchBusdRefs(busdId,memberId);
	}

	/**
     * 保存商品注册送礼
     * @param gift
     */
	private void saveGiftSpu(Gift gift) {
		List<GiftGoodsRef> refs = gift.getRefs();
		GiftCommodityType commodityType = gift.getCommodityType();
        if (gift.getActivityEndTime().isBefore(LocalDateTime.now())) {
            throw new DragonException(ActivityCode.ACTIVITY_TIME_IS_NOT_CORRECT);
        }
		baseMapper.insert(gift);
		for (GiftGoodsRef ref : refs) {
			SkuEntity sku = skuService.getById(ref.getArticleId());
			SpuEntity spu = spuService.getById(sku.getSpuId());
			String articleId = ref.getArticleId();
			if (!GiftCommodityType.POINTS.equals(commodityType)&&StringUtils.isEmpty(articleId)) {
				throw new DragonException(ActivityCode.SKU_NOT_EXIST);
			}
			if (spu.getEndTime().isBefore(gift.getActivityEndTime())) {
				throw new DragonException(ActivityCode.ACTIVITY_TIME_IS_BEFORE_END_TIME);
			}
			ref.setGiftId(gift.getId());
			ref.setDel(false);
			ref.setCommodityName(sku.getTitle());
			ref.setCreatedBy(gift.getCreatedBy());
			ref.setCreatedTime(LocalDateTime.now());
			giftGoodsRefService.save(ref);

		}

    }

	/**
	 * 保存停车券注册送礼
	 * @param gift
	 */
	private void saveGiftPark(Gift gift) {
		List<GiftGoodsRef> refs = gift.getRefs();
		if (gift.getActivityEndTime().isBefore(LocalDateTime.now())) {
			throw new DragonException(ActivityCode.ACTIVITY_TIME_IS_NOT_CORRECT);
		}
		baseMapper.insert(gift);
		for (GiftGoodsRef ref : refs) {
			Check.notNull(ref.getArticleId(),"请确认活动物品");
			CouponTemplateEntity template = couponTemplateService.getById(ref.getArticleId());
			if (Objects.nonNull(template.getEndTime())&&template.getEndTime().isBefore(gift.getActivityEndTime())) {
				throw new DragonException(ActivityCode.ACTIVITY_TIME_IS_BEFORE_END_TIME);
			}
			ref.setGiftId(gift.getId());
			ref.setDel(false);
			ref.setCommodityName(template.getTitle());
			ref.setCreatedBy(gift.getCreatedBy());
			ref.setCreatedTime(LocalDateTime.now());
			giftGoodsRefService.save(ref);

		}
	}

	/**
	 * 保存积分注册送礼
	 * @param gift
	 */
	private void saveGiftPoint(Gift gift) {
		List<GiftGoodsRef> refs = gift.getRefs();
		if (gift.getActivityEndTime().isBefore(LocalDateTime.now())) {
			throw new DragonException(ActivityCode.ACTIVITY_TIME_IS_NOT_CORRECT);
		}
		baseMapper.insert(gift);
		for (GiftGoodsRef ref : refs) {
			ref.setArticlePoints(ref.getQuantity());
			ref.setQuantity(1);
			Check.digits(ref.getArticlePoints(),10,0,"请确认积分");
			if (Objects.isNull(ref.getArticlePoints()) || ref.getArticlePoints() <= 0) {
				throw new DragonException(PointsCode.NOT_NULL_POINT);
			}
			ref.setGiftId(gift.getId());
			ref.setDel(false);
			ref.setCreatedBy(gift.getCreatedBy());
			ref.setCreatedTime(LocalDateTime.now());
			ref.setCommodityName("积分");
			giftGoodsRefService.save(ref);

		}
	}
}